package com.ruoyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.InvInventoryTransferMapper;
import com.ruoyi.system.service.*;
import com.ruoyi.system.util.AbdulEmptyUtils;
import com.ruoyi.system.util.BaseResponse;
import com.ruoyi.system.util.BookingNumberGenerator;
import com.ruoyi.system.util.StoreIdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 库存调拨Service业务层处理
 *
 * @author ruoyi
 * @date 2023-07-18
 */
@Service
public class InvInventoryTransferServiceImpl extends ServiceImpl<InvInventoryTransferMapper, InvInventoryTransfer> implements IInvInventoryTransferService {

    @Autowired
    private IWarehouseService warehouseService;

    @Autowired
    private StoreIdUtils storeIdUtils;

    @Autowired
    private IInvInventoryTransferDetailService invInventoryTransferDetailService;

    @Autowired
    private IProductInventoryService productInventoryService;

    @Autowired
    private IProductManagementService productManagementService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(InvInventoryTransfer invInventoryTransfer) {
        check(invInventoryTransfer);
        invInventoryTransfer.setOutboundOrderNo(BookingNumberGenerator.generateBookingNumber());
        invInventoryTransfer.setStoreId(storeIdUtils.getStoreId());
        invInventoryTransfer.setCreateBy(SecurityUtils.getUsername());
        this.save(invInventoryTransfer);
        List<InvInventoryTransferDetail> detailList = invInventoryTransfer.getInvInventoryTransferDetailList();
        if (AbdulEmptyUtils.isEmpty(detailList)) {
            throw new RuntimeException("调拨详情不能为空");
        }
        editCheck(detailList, invInventoryTransfer.getId());
//        for (InvInventoryTransferDetail detail : detailList) {
//            detail.setTransferId(invInventoryTransfer.getId());
//            detail.setStoreId(storeIdUtils.getStoreId());
//            detail.setCreateBy(SecurityUtils.getUsername());
//            if (AbdulEmptyUtils.isEmpty(detail.getProductManagementId())) {
//                throw new RuntimeException("商品id不能为空");
//            }
//            if (AbdulEmptyUtils.isEmpty(detail.getStockPrice())) {
//                throw new RuntimeException("商品单价不能为空");
//            }
//            if (AbdulEmptyUtils.isEmpty(detail.getStockQuantity()) || detail.getStockQuantity() <= 0) {
//                throw new RuntimeException("库存数量为空或者库存数量小于0");
//            }
//            if (AbdulEmptyUtils.isEmpty(detail.getTransferQuantity()) || detail.getTransferQuantity() <= 0) {
//                throw new RuntimeException("调拨数量为空或者调拨数量小于0");
//            }
//
//            if (detail.getStockQuantity() < detail.getTransferQuantity()) {
//                throw new RuntimeException("库存数量不能小于调拨数量");
//            }
//        }
        return invInventoryTransferDetailService.saveBatch(detailList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean audit(Long id) {
        if (AbdulEmptyUtils.isEmpty(id)) {
            throw new RuntimeException("参数ID不能为空");
        }
        //审核 1-更新状态 2-出库仓库数量减少 3-入库仓库数量增加
        InvInventoryTransfer transfer = this.getById(id);
        if (AbdulEmptyUtils.isEmpty(transfer)) {
            throw new RuntimeException("审核失败,调拨单不存在");
        }

        LambdaQueryWrapper<InvInventoryTransferDetail> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(InvInventoryTransferDetail::getTransferId, id);
        List<InvInventoryTransferDetail> list = invInventoryTransferDetailService.list(wrapper); //查询这次需要调拨的数据
        if (AbdulEmptyUtils.isEmpty(list)) {
            throw new RuntimeException("审核失败,调拨单详情不存在");
        }
        Map<Long, Integer> result = list.stream()
                .collect(Collectors.toMap(
                        InvInventoryTransferDetail::getProductManagementId,
                        InvInventoryTransferDetail::getTransferQuantity
                ));

        Map<Long, InvInventoryTransferDetail> transferDetailMap = list.stream()
                .collect(Collectors.toMap(
                        InvInventoryTransferDetail::getProductManagementId,
                        e -> e,
                        (key1, key2) -> key1
                ));

        //审核的时候 判断原始仓库的库存中数量是否大于本次挑拨的 数量
        // 2-门店商品库存数量减少
        Set<Long> productIds = list.stream().map(InvInventoryTransferDetail::getProductManagementId).collect(Collectors.toSet());
        LambdaQueryWrapper<ProductInventory> lqw = Wrappers.lambdaQuery();
        lqw.in(ProductInventory::getProductManagementId, productIds);
        lqw.eq(ProductInventory::getWarehouseId, transfer.getOutWarehouse());
        List<ProductInventory> outProductInventoryList = productInventoryService.list(lqw); //门店商品库存
        if (AbdulEmptyUtils.isEmpty(outProductInventoryList)) {
            throw new RuntimeException("审核失败,门店商品库存不存在");
        }
        for (ProductInventory productInventory : outProductInventoryList) {
            if (productInventory.getStockQuantity() < result.get(productInventory.getProductManagementId())) {
                throw new RuntimeException("调拨失败,门店商品[" + productInventory.getName() + "]库存不足");
            }
            productInventory.setStockQuantity(productInventory.getStockQuantity() - result.get(productInventory.getProductManagementId()));
            if (productInventory.getStockQuantity() < productInventory.getMinStock()) {
                productInventory.setStockWarning(1);
            }
        }
        productInventoryService.updateBatchById(outProductInventoryList);
        //3-入库仓库数量增加
        //3.1 查询入库仓库是否存在调拨商品 有则就修改库存数量 否则就新增
        LambdaQueryWrapper<ProductInventory> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(ProductInventory::getWarehouseId, transfer.getInWarehouse());
        lambdaQuery.in(ProductInventory::getProductManagementId, productIds);
        List<ProductInventory> inProductInventoryList = productInventoryService.list(lambdaQuery);
        Map<Long, ProductInventory> productInventoryMap = inProductInventoryList.stream().collect(Collectors.toMap(ProductInventory::getProductManagementId, e -> e));

        // 构建已存在商品 ID 的 Set
        Set<Long> existingProductIds = inProductInventoryList.stream()
                .map(ProductInventory::getProductManagementId)
                .collect(Collectors.toSet());

        List<ProductInventory> updateList = new ArrayList<>();  //仓库中 原本有的商品 只需要更改他的库存数量
        List<ProductInventory> insertList = new ArrayList<>(); //仓库中没有的商品 需要新增

        for (Long existingProductId : existingProductIds) {
            ProductInventory productInventory = productInventoryMap.get(existingProductId);
            productInventory.setStockQuantity(productInventory.getStockQuantity() + result.get(productInventory.getProductManagementId()));
            if (productInventory.getStockQuantity() < productInventory.getMinStock()) {
                productInventory.setStockWarning(1);
            }
            if (productInventory.getStockQuantity() > productInventory.getMaxStock()) {
                productInventory.setStockWarning(2);
            }
            if (productInventory.getStockQuantity() >= productInventory.getMinStock() && productInventory.getStockQuantity() <= productInventory.getMaxStock()) {
                productInventory.setStockWarning(0);
            }
            updateList.add(productInventory);
        }

        // 找出需要新增的商品 ID（productIds 中不在 existingProductIds 的）
        List<Long> missingProductIds = productIds.stream()
                .filter(productId -> !existingProductIds.contains(productId))
                .collect(Collectors.toList());
        //查询商品信息
        LambdaQueryWrapper<ProductManagement> productManagementWrapper = Wrappers.lambdaQuery();
        productManagementWrapper.in(ProductManagement::getId, missingProductIds);
        List<ProductManagement> productManagementList = productManagementService.list(productManagementWrapper); //这些商品需要添加到门店库存表
        if (AbdulEmptyUtils.isEmpty(productManagementList)) {
            throw new RuntimeException("审核失败，调拨商品不存在商品库里面");
        }
        productManagementList.forEach(productManagement -> {
            InvInventoryTransferDetail detail = transferDetailMap.get(productManagement.getId());
            if (AbdulEmptyUtils.isEmpty(detail)) {
                throw new RuntimeException("审核失败,调拨商品不存在商品库里面");
            }
            ProductInventory productInventory = new ProductInventory();
            productInventory.setProductManagementId(productManagement.getId());
            productInventory.setWarehouseId(transfer.getInWarehouse());
            productInventory.setStockQuantity(result.get(productManagement.getId()));
            productInventory.setMinStock(Math.toIntExact(productManagement.getInventoryWarning()));
            productInventory.setMaxStock(Math.toIntExact(productManagement.getInventoryMax()));
            if (productInventory.getStockQuantity() < productInventory.getMinStock()) {
                productInventory.setStockWarning(1);
            } else if (productInventory.getStockQuantity() > productInventory.getMaxStock()) {
                productInventory.setStockWarning(2);
            } else {
                productInventory.setStockWarning(0);
            }
            productInventory.setUnitPrice(detail.getStockPrice());
            productInventory.setSellingPrice(productManagement.getSellingPrice());
            productInventory.setName(detail.getProductName());
            productInventory.setCategory(detail.getCategory());
            productInventory.setClassification(detail.getClassification());
            productInventory.setUnit(detail.getUnit());
            productInventory.setInStock(productManagement.getParticipateInventory());
            productInventory.setCode(BookingNumberGenerator.generateBookingNumber());
            productInventory.setStoreId(storeIdUtils.getStoreId());
            productInventory.setSpecification(detail.getSpecifications());
            productInventory.setCreateBy(SecurityUtils.getUsername());
            insertList.add(productInventory);
        });
        if (!insertList.isEmpty()) {
            productInventoryService.saveBatch(insertList);
        }
        if (!updateList.isEmpty()) {
            productInventoryService.updateBatchById(updateList);
        }
        transfer.setTransferOrderNo(BookingNumberGenerator.generateBookingNumber());
        transfer.setIsStatus(2);
        transfer.setUpdateBy(SecurityUtils.getUsername());
        return this.updateById(transfer);
    }

    @Override
    public Boolean edit(InvInventoryTransfer invInventoryTransfer) {
        if (AbdulEmptyUtils.isEmpty(invInventoryTransfer.getId())) {
            throw new RuntimeException("调拨单ID不能为空");
        }
        InvInventoryTransfer transfer = this.getById(invInventoryTransfer.getId());
        if (AbdulEmptyUtils.isEmpty(transfer)) {
            throw new RuntimeException("调拨单不存在");
        }
        LambdaQueryWrapper<InvInventoryTransferDetail> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(InvInventoryTransferDetail::getTransferId, invInventoryTransfer.getId());
        List<InvInventoryTransferDetail> list = invInventoryTransferDetailService.list(wrapper);
        if (!AbdulEmptyUtils.isEmpty(list)) {
            invInventoryTransferDetailService.removeBatchByIds(list);
        }
        if (!AbdulEmptyUtils.isEmpty(invInventoryTransfer.getTransferTime())) {
            transfer.setTransferTime(invInventoryTransfer.getTransferTime());
        }
        if (!AbdulEmptyUtils.isEmpty(invInventoryTransfer.getTransferStaff())) {
            transfer.setTransferStaff(invInventoryTransfer.getTransferStaff());
        }
        if (!AbdulEmptyUtils.isEmpty(invInventoryTransfer.getRemark())) {
            transfer.setRemark(invInventoryTransfer.getRemark());
        }
        if (AbdulEmptyUtils.isEmpty(invInventoryTransfer.getInvInventoryTransferDetailList())) {
            throw new RuntimeException("调拨单详情不能为空");
        }
        editCheck(invInventoryTransfer.getInvInventoryTransferDetailList(), invInventoryTransfer.getId());
        invInventoryTransferDetailService.saveBatch(invInventoryTransfer.getInvInventoryTransferDetailList());

        return null;
    }


    /**
     * 参数效验
     *
     * @param invInventoryTransfer 调拨单
     */
    public void check(InvInventoryTransfer invInventoryTransfer) {
        if (AbdulEmptyUtils.isEmpty(invInventoryTransfer.getOutWarehouse())) {
            throw new RuntimeException("调出仓库不能为空");
        }
        Warehouse warehouse = warehouseService.getById(invInventoryTransfer.getOutWarehouse());
        if (AbdulEmptyUtils.isEmpty(warehouse)) {
            throw new RuntimeException("调出仓库不存在");
        }
        if (AbdulEmptyUtils.isEmpty(invInventoryTransfer.getInWarehouseType())) {
            throw new RuntimeException("调入仓库类型不能为空");
        }
        if (AbdulEmptyUtils.isEmpty(invInventoryTransfer.getInWarehouse())) {
            throw new RuntimeException("调入仓库不能为空");
        }
        Warehouse warehouse1 = warehouseService.getById(invInventoryTransfer.getInWarehouse());
        if (AbdulEmptyUtils.isEmpty(warehouse1)) {
            throw new RuntimeException("调入仓库不存在");
        }
        if (AbdulEmptyUtils.isEmpty(invInventoryTransfer.getTransferStaff())) {
            throw new RuntimeException("调拨员工不能为空");
        }
        if (AbdulEmptyUtils.isEmpty(invInventoryTransfer.getTransferTime())) {
            throw new RuntimeException("调拨时间不能为空");
        }
        if (AbdulEmptyUtils.isEmpty(invInventoryTransfer.getTransferQuantity())) {
            throw new RuntimeException("调拨数量不能为空");
        }
        if (invInventoryTransfer.getTransferQuantity() <= 0) {
            throw new RuntimeException("调拨数量必须大于0");
        }
        if (AbdulEmptyUtils.isEmpty(invInventoryTransfer.getTotalValue())) {
            throw new RuntimeException("调拨总值不能为空");
        }
    }

    public void editCheck(List<InvInventoryTransferDetail> detailList, Long id) {
        for (InvInventoryTransferDetail detail : detailList) {
            detail.setTransferId(id);
            detail.setStoreId(storeIdUtils.getStoreId());
            detail.setCreateBy(SecurityUtils.getUsername());
            detail.setDetailType(1);
            if (AbdulEmptyUtils.isEmpty(detail.getProductManagementId())) {
                throw new RuntimeException("商品id不能为空");
            }
            if (AbdulEmptyUtils.isEmpty(detail.getStockPrice())) {
                throw new RuntimeException("商品单价不能为空");
            }
            if (AbdulEmptyUtils.isEmpty(detail.getStockQuantity()) || detail.getStockQuantity() <= 0) {
                throw new RuntimeException("库存数量为空或者库存数量小于0");
            }
            if (AbdulEmptyUtils.isEmpty(detail.getTransferQuantity()) || detail.getTransferQuantity() <= 0) {
                throw new RuntimeException("调拨数量为空或者调拨数量小于0");
            }

            if (detail.getStockQuantity() < detail.getTransferQuantity()) {
                throw new RuntimeException("库存数量不能小于调拨数量");
            }
        }
    }
}
